#include "KidGameState.h"

Test2 Test2::m_Test2;

// The scale of the bank and the coins
sf::Vector2f bankScale = sf::Vector2f(.7, .7);

// Update the text displaying the coin total
void Test2::updateTotal(){
    textList[1].setString(Utility::toString(coinTotal/100) + " Dollars" + "    " +
                          Utility::toString(coinTotal%100) + " Cents");
}

void Test2::Init(sf::RenderWindow& window){

    //Coins
    int numberOfSets = 5;
    int j[4] = {1, 5, 10, 25};
    // Add one of each coin for the number of sets, random distributed across the right side of the screen
    for(int i = 0; i < numberOfSets; i++){
        for(int k : j){
            coinList.push_back(new Coin(k, sf::Vector2f(Utility::random(800,window.getSize().x - 100),
                                                        Utility::random(50,window.getSize().y - 50)), bankScale));
        }
    }
    activeCoin = -1;    //start with active coin not equal to any coin.

    // ++ Clock ++
    clock.restart();

    // +++ VIEWS +++
    view.setCenter(window.getSize().x / 2, window.getSize().y / 2);
    view.setSize(window.getSize().x, window.getSize().y);
    window.setView(view);

    // ++ TGUI STUFF ++
    gui.setWindow(window);
    gui.setGlobalFont("resources/arial.ttf");

    //child window
    tgui::ChildWindow::Ptr cWindow(gui);
    cWindow->load("resources/Black.conf");
    cWindow->setSize(200,240);
    cWindow->setPosition(25 ,500);

    // button
    tgui::Button::Ptr button2(*cWindow);
    button2->load("resources/Black.conf");
    button2->setSize(150, 25);
    button2->setPosition(25, 10);
    button2->setText("Return to Menu");
    button2->bindCallback(tgui::Button::LeftMouseClicked);
    button2->setCallbackId(1);
    button2->setTextColor(sf::Color::White);

    // Widget Selector Combo Box
    tgui::ComboBox::Ptr comboBox(*cWindow);
    comboBox->load("resources/Black.conf");
    comboBox->setSize(cWindow->getSize().x * .75 ,25);
    comboBox->setPosition( 10, 50);
    comboBox->bindCallback(tgui::Button::LeftMouseClicked);
    comboBox->setCallbackId(4);
    comboBox->setTextColor(sf::Color::Green);
    comboBox->addItem("Quarter");
    comboBox->addItem("Dime");
    comboBox->addItem("Nickel");
    comboBox->addItem("Penny");
    comboBox->setSelectedItem(0);
    c1 = comboBox;

    // Clear button
    tgui::Button::Ptr button3(*cWindow);
    button3->load("resources/Black.conf");
    button3->setSize(150, 25);
    button3->setPosition(25, 180);
    button3->setText("Clear Coins");
    button3->bindCallback(tgui::Button::LeftMouseClicked);
    button3->setCallbackId(2);
    button3->setTextColor(sf::Color::White);

    //bank background
    spTexture.loadFromFile("resources/bank.png");
    sprite.setTexture(spTexture);
    sprite.setPosition(sf::Vector2f(0,0));
    sprite.setScale(bankScale);
    spriteList.push_back(sprite);

    // Bank vault Rectangle
    sf::Rect<float> tempRec = spriteList[0].getGlobalBounds();
    //size rectangle based on bank
    rectangle1.setSize(sf::Vector2f(tempRec.width * .5, tempRec.height *.44 ));
    //position rectangle inside bank vault
    rectangle1.setPosition(tempRec.left + (tempRec.width - rectangle1.getSize().x)/2 ,
                           tempRec.top + tempRec.height * .4);
    rectangle1.setFillColor(sf::Color::Transparent);
    rectangle1.setOutlineColor(sf::Color::Black);
    rectangle1.setOutlineThickness(4);

    // +++ TEXT +++
    text1.setCharacterSize(24);
    text1.setString("Left Click to Add Coins");
    text1.scale(bankScale);
    text1.setPosition(tempRec.left + tempRec.width * .3 , tempRec.top + tempRec.height * .8);
    textList.push_back(text1);
    // coins
    textList.push_back(text1);
    updateTotal();
    textList[1].setPosition(spriteList[0].getPosition().x + spriteList[0].getGlobalBounds().width /2 - textList[1].getGlobalBounds().width / 2,
                      rectangle1.getPosition().y - rectangle1.getGlobalBounds().height * .24 );

    //speed of coin movement
    spriteSpeed = 60;
    //selected coin is moving
    start = false;

}

void Test2::Cleanup(){}

void Test2::Pause(){}
void Test2::Resume(){}

void Test2::Events(GameEngine* game, sf::RenderWindow& window){

        while (window.pollEvent(event))
        {
            gui.handleEvent(event);

            // The callback loop
            tgui::Callback callback;
            while (gui.pollCallback(callback)){

                // Return to introState
                if (callback.id == 1){
                    game->ChangeState(IntroState::Instance() );
                }

                // Clear Coins
                if (callback.id == 2){
                    coinList.clear();
                    coinTotal = 0;
                    updateTotal();
                }
            }

            // "close requested" event: we close the window
            if (event.type == sf::Event::Closed){
                game->Quit();
            }

            // Mouse Events
            if (event.type == sf::Event::MouseButtonPressed){

                //get current mouse position
                sf::Vector2f tempPos = (sf::Vector2f)sf::Mouse::getPosition(window);

                //Left click
                if(event.mouseButton.button == sf::Mouse::Left){

                    //Select a coin if it is clicked and it's not already in the bank
                    for(int i = 0; i < coinList.size(); i ++){
                        if (coinList[i]->isClicked(tempPos) && !rectangle1.getGlobalBounds().contains(tempPos)){

                            //set the active coin to clicked coin
                            activeCoin = i;

                            //set a destination inside the bank rectangle
                            p3 = sf::Vector2f(rectangle1.getPosition().x + rectangle1.getGlobalBounds().width / 2,
                                               rectangle1.getPosition().y + rectangle1.getGlobalBounds().height / 2);

                        //calculate the unit vector between the two points
                            //determine the vector (x2-x1, y2-y1)
                                //center of the selected coin
                            p2 = sf::Vector2f(coinList[i]->sprite.getPosition().x + coinList[i]->sprite.getGlobalBounds().width/2,
                                coinList[i]->sprite.getPosition().y + coinList[i]->sprite.getGlobalBounds().height/2);

                            //vector between two points
                            sf::Vector2f sVec = p3-p2;
                            //determine the magnitude
                            double mag = sqrt((sVec.x * sVec.x) + (sVec.y * sVec.y));
                            //subtract divide both x and y by the magnitude to get unit (used in the update method to move)
                            unitVec = sf::Vector2f(sVec.x / mag, sVec.y / mag);
                            start = true;
                        }
                    }

                    //Add coins if the user clicks inside the bank
                    /*
                    if(rectangle1.getGlobalBounds().contains(tempPos)){

                        int tempValue = 0;
                        switch(c1->getSelectedItemIndex()){
                            case 0:
                                tempValue = 25;
                                break;
                            case 1:
                                tempValue = 10;
                                break;
                            case 2:
                                tempValue = 5;
                                break;
                            case 3:
                                tempValue = 1;
                                break;
                        }

                       //add coin to the bank and update the coin total
                       coinList.push_back(new Coin(tempValue, tempPos, bankScale));
                       coinTotal += coinList.back()->getValue();
                       updateTotal();
                    }
                    */
                }
            }
/*
            //control continuous mouse clicks
            if (sf::Mouse::isButtonPressed(sf::Mouse::Left)){
            }

            //mouse button released

            if (event.type == sf::Event::MouseButtonReleased){
                if(event.mouseButton.button == sf::Mouse::Left){
                }
            }

           //other method for keyboard events
            if (event.type == sf::Event::KeyPressed){
                if (event.key.code == sf::Keyboard::Right){
                }

                if (event.key.code == sf::Keyboard::Space){
                }
            }
*/
        }
}

void Test2::Update(GameEngine* game, sf::RenderWindow& window){

//Move the active coin
    //move the point along the unit vector by the speed rate
    if(start && activeCoin >= 0) {

        //set the position of the activeCoin sprite
         coinList[activeCoin]->sprite.setPosition(sf::Vector2f(coinList[activeCoin]->sprite.getPosition().x + spriteSpeed * unitVec.x,
                                         coinList[activeCoin]->sprite.getPosition().y + spriteSpeed * unitVec.y ));
        //update the location of the coin
        p2 = sf::Vector2f(coinList[activeCoin]->sprite.getPosition().x + coinList[activeCoin]->sprite.getGlobalBounds().width/2,
                             coinList[activeCoin]->sprite.getPosition().y + coinList[activeCoin]->sprite.getGlobalBounds().height/2);

        //stop when the distance between the two points is less than the speed rate and add coin to total
        if(Utility::computeDistance(p3,p2) < spriteSpeed){
            start = !start ;
            coinTotal += coinList[activeCoin]->getValue();
            activeCoin = -1;
            updateTotal();
        }
    }

}

void Test2::Render(GameEngine* game, sf::RenderWindow& window){

    // clear the window with black color
    window.clear(sf::Color::White);

    gui.draw();

    //draw all sprite entities
    for(int i = 0;i < spriteList.size();i++) {
        window.draw(spriteList[i]);
    }

    //draw the bank rectangle
    //window.draw(rectangle1);

    //draw the rect of the bank sprite
    sf::RectangleShape r;
    r.setSize(sf::Vector2f(spriteList[0].getGlobalBounds().width, spriteList[0].getGlobalBounds().height)) ;
    r.setFillColor(sf::Color::Transparent);
    r.setOutlineColor(sf::Color::Blue);
    r.setOutlineThickness(3);
    r.setPosition(spriteList[0].getPosition());
    //window.draw(r);

    //draw all text
    for(int i = 0; i < textList.size();i++) {
        window.draw(textList[i]);
    }

    //draw all coin entities
    for(int i = 0;i < coinList.size();i++) {
        window.draw(coinList[i]->sprite);
    }

    //draw a line between the first coin and a point inside the bank
    //window.draw(line,2,sf::Lines);

    window.display();

}
